#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <hi_i2c.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "keyevent/KeyEvent.h"
#include "wifi/ap_mode.h"
#include "wifi/sta_mode.h"
#include "oled/oled.h"
#include "mqtt/mqtt_fun.h"
#include "gpio/led.h"

char* wifi_name = "Duoduo";//Wifi SSID
char* wifi_password = "duoduo8090";//Wifi 密码

volatile char start_wifi_config_flg = 0;//Wifi 是否开启连接标志位
volatile char wifi_connect_ok_flg = 0;//Wifi 连接状态标志位
volatile char start_MQTT_Task_flg = 0;//开启MQTT 连接标志位
int MQTT_Connect_flag = 0;//MQTT 连接标志位

//订阅的主题
static const char* gMessage[] = {
    "ledstatus",
    NULL
};

//LED 对应的字符串
static const char* gLEDName[] = {
    "UnkownLED","RedLED",  "YellowLED",  "GreenLED", 
    NULL
};

//重新连上MQTT broker后进行状态同步
static void LED_Status_Sync(void){
    int ret = -1;

    if(start_wifi_config_flg == 0 || start_MQTT_Task_flg == 0){
        return;
    }

    ret = LEDStatus(LED_ID_R);
    if(ret == 1)
        MQTT_Public_Topic("ledstatus", "RedOn");
    else if(ret == 0)
        MQTT_Public_Topic("ledstatus", "RedOff");

    usleep(100000);

    ret = LEDStatus(LED_ID_Y);
    if(ret == 1)
        MQTT_Public_Topic("ledstatus", "YellowOn");
    else if(ret == 0)
        MQTT_Public_Topic("ledstatus", "YellowOff");

    usleep(100000);
    ret = LEDStatus(LED_ID_G);
    if(ret == 1)
        MQTT_Public_Topic("ledstatus", "GreenOn");
    else if(ret == 0)
        MQTT_Public_Topic("ledstatus", "GreenOff");
}

//翻转对应LED的状态，将状态更新到OLED 屏幕，并判断是否需要发送 MQTT 消息
static void LED_Status_Change(LED_ID_TYPE ledid){
    int ret = -1;
    char *chrtosend = NULL;
    ret = LEDToggle(ledid);
    switch(ledid){
        case LED_ID_R:
            if(ret == 1)
                chrtosend = "RedOn";
            else if(ret == 0)
                chrtosend = "RedOff";
            break;
        case LED_ID_Y:
            if(ret == 1)
                chrtosend = "YellowOn";
            else if(ret == 0)
                chrtosend = "YellowOff";
            break;
        case LED_ID_G:
            if(ret == 1)
                chrtosend = "GreenOn";
            else if(ret == 0)
                chrtosend = "GreenOff";
            break;
        default:
            break;
    }
    if(chrtosend != NULL){
        if(start_wifi_config_flg == 1 && start_MQTT_Task_flg == 1){
            MQTT_Public_Topic("ledstatus", chrtosend);
        }
        OLED_Clear();
        OLED_ShowString(8,16,chrtosend,16);
        OLED_Refresh();
    }
}

//MQTT 订阅消息的回调函数
static void MQTT_Callback(char* ptopic,char* pdata)
{
    const char* rtopic = (const char*)ptopic;
    const char* rdata = (const char*)pdata;
    if(strcmp(gMessage[0], rtopic) == 0 ){
        if(strcmp(gLEDName[1], rdata) == 0 ){
            LED_Status_Change(LED_ID_R);
        }else if( strcmp(gLEDName[2], rdata) == 0 ){
            LED_Status_Change(LED_ID_Y);
        }else if( strcmp(gLEDName[3], rdata) == 0 ){
            LED_Status_Change(LED_ID_G);
        }
    }
}

//MQTT 连接状态的回调函数，负责断线重连
static void MQTT_Status_Callback(int status)
{
    int ret = 0;
    MQTT_Connect_flag = status;
    if(MQTT_Connect_flag == 0)
    {
        if(MQTT_Connect_flag == 0){
            MQTT_UnSubscribe_Topic("ledstatus");
            MQTT_Disconnect();
        }
        for(uint8_t t = 0; t < 5; t++)
        {
            char *chrtosend = NULL;
            ret = MQTT_Connect();
            if(ret == MQTT_ACK_CONNET)
            {
                chrtosend = "MQTT Connect";
            }
            else if(ret == MQTT_ACK_SOCKET_ERR)
            {
                chrtosend = "Socket ERR";
            }
            else if(ret == MQTT_ACK_CONNET_BADACK)
            {
                chrtosend = "MQTT Bad ACK";
            }
            else if(ret == MQTT_ACK_NOACK)
            {
                chrtosend = "MQTT NOACK";
            }else if (ret == 37){
                //连接成功，开始订阅主题并注册收到消息后的回调函数MQTT_Callback
                MQTT_Subscribe_Topic("ledstatus", MQTT_Callback);
                printf("MQTT_Subscribe_Topic status is %d\r\n",ret);
                chrtosend = "Subscribe ok";
                MQTT_Connect_flag = 1;
                LED_Status_Sync();
            }
            printf("init status is %d\r\n",ret);
            if(chrtosend != NULL){
                OLED_Clear();
                OLED_ShowString(8,16,chrtosend,16);
                OLED_Refresh();
            }
            if(ret == 37){
                break;
            }
            sleep(2);
        }
    } else {
        printf("MQTT status good\r\n");
    }
}

//按键处理的回调函数，负责处理按键执行动作
static void KeyEvent_Callback(KEY_ID_TYPE keyid, KEY_EVENT_TYPE event)
{
    printf("[soon] KeyEvent_Callback() : keyid=%d event= %d\n", (int)keyid, (int)event);
    //char* str ="wait key press"
    switch (keyid)
    {
    case KEY_ID_USER:
        if( event == KEY_EVENT_PRESSED ){ /*  按下事件处理代码 */ }
        if( event == KEY_EVENT_LONG_PRESSED )
        { 

         }
        if( event == KEY_EVENT_RELEESED ){ 
            //启动配网功能
            if(start_wifi_config_flg == 0){
                start_wifi_config_flg = 1;
            } 
        }
        break;
    case KEY_ID_S1:
         printf("[soon] KEY_ID_S1\n");
        if( event == KEY_EVENT_PRESSED ){ 

        }
        if( event == KEY_EVENT_LONG_PRESSED ) { 

        }
        if( event == KEY_EVENT_RELEESED ){ 
            //启动MQTT_Task
            if(start_wifi_config_flg == 1 && start_MQTT_Task_flg == 0){
                start_MQTT_Task_flg = 1;
            }
            else
            {
                LED_Status_Change(LED_ID_R);
            }
         }
        break;
    case KEY_ID_S2:
         printf("[soon] KEY_ID_S2\n");
        if( event == KEY_EVENT_PRESSED )      { /*  按下事件处理代码 */ }
        if( event == KEY_EVENT_LONG_PRESSED ) { /*  长按事件处理代码 */ }
        if( event == KEY_EVENT_RELEESED ){ 
            LED_Status_Change(LED_ID_Y);
        }
        break;
    case KEY_ID_GPIO8:
        if( event == KEY_EVENT_PRESSED ){ 

        }
        if( event == KEY_EVENT_LONG_PRESSED ) { 

         }
        if( event == KEY_EVENT_RELEESED )    { 
            LED_Status_Change(LED_ID_G);
        }
        break;
    
    default:
        break;
    }

}

//MQTT LED Task
static void* MQTT_LED_Task(const char* arg)
{
    int ret = 0;

    printf("[soon] MQTTLED_Task()\n");

    (void)arg;

    ret += KeyEvent_Init(); // 初始化按键事件处理上下文

    /* 设置GPIO_8 GPIO_5按键的回调函数，同时需要响应按下，释放以及长按三个事件 */

    ret += KeyEvent_Connect("GPIO_8", KeyEvent_Callback, KEY_EVENT_PRESSED | KEY_EVENT_LONG_PRESSED | KEY_EVENT_RELEESED);

    ret += KeyEvent_Connect("GPIO_5", KeyEvent_Callback, KEY_EVENT_PRESSED | KEY_EVENT_LONG_PRESSED | KEY_EVENT_RELEESED);

    if( ret == 0 )
    {
        //等待USER 按键按下start_wifi_config_flg ==1
        while(start_wifi_config_flg == 0)
        {
            usleep(100000);
        }
        //USER 按键被按下开始联网 在OLED 上显示WIFI Start
        printf("wifi_start \r\n");
        OLED_Clear();
        OLED_ShowString(8,16,"WIFI Start",16);
        OLED_Refresh();
        //等待WIFI 连接成功
        while (wifi_connect_ok_flg == 0)
        {
            //连接指定wifi
            //Todo wifi 连接成功的判断还需要改进
			wifi_connect_ok_flg = start_sta_connect(wifi_name, strlen(wifi_name), wifi_password, strlen(wifi_password));
            if(wifi_connect_ok_flg == 0){
                sleep(3);
                start_sta_disconnect();
            } else {
                break;
            }
            

        }
        //显示wifi 连接成功
        OLED_Clear();
        OLED_ShowString(8,16,"WIFI OK",16);
        OLED_Refresh();

        //等待OLED 按键1 按下
        while(start_wifi_config_flg == 1 && start_MQTT_Task_flg == 0)
        {
            usleep(100000);
        }
        //显示MQTT 开始连接
        OLED_ShowString(8,16,"MQTT Start",16); 
        OLED_Refresh();
        OLED_Clear();

        //初始化MQTT Task
        ret = MQTT_Init();
        
        if(ret == -1){
            printf("MQTT_Init fail \r\n");
            return NULL;
        }

        //先做一次connect和订阅
        MQTT_Status_Callback(0);
        
        //注册MQTT Ping REQ的回调函数，相关的消息订阅在 MQTT_Status_Callback 函数中连接成功后执行
        MQTT_PingREQ_Callback(MQTT_Status_Callback);
    }
    else
    {
        printf("[soon] Falied to enable button!\n");
        KeyEvent_Disconnect("GPIO_8");  // 取消 GPIO_8 按键的所有按键事件
        KeyEvent_Disconnect("GPIO_5");  // 取消 GPIO_5 按键的所有按键事件

        KeyEvent_Close(); // 关闭按钮事件处理上下文
    }

    return NULL;
}

void oled_config(void)
{
    //初始化I2C
    hi_i2c_init(HI_I2C_IDX_0, 100000); /* baudrate: 100000 */
    //OLED 初始化
    OLED_Init();

    OLED_ColorTurn(0);//0正常显示，1 反色显示
    OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
    //开机信息读取
    OLED_ShowInit_Info();    
    //显示开机信息
    OLED_Refresh();

}

static void MQTT_LED_Entry(void)
{
    osThreadAttr_t attr = {0};

    printf("[soon] MQTT_LED_Entry()\n");

    oled_config();//OLED display init

    LED_Init();//LED gpio init

    attr.name = "MQTT_LED_Task";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 8192;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)MQTT_LED_Task, NULL, &attr) == NULL)
    {
        printf("[soon] Falied to create MQTT LED_Task!\n");
    }
}

SYS_RUN(MQTT_LED_Entry);